﻿using Com.Lancetinc.Evs.Cameras;
using Com.Lancetinc.Evs.Communications;
using Com.Lancetinc.Evs.Helpers;
using Com.Lancetinc.Evs.Models;
using Com.Lancetinc.Evs.Properties;
using Com.Lancetinc.Evs.Windows;
using NLog;
using System;
using System.Threading.Tasks;
using System.Windows;

namespace Com.Lancetinc.Evs.Services
{
    public static class VideoStartRecordHelper
    {
        private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();

        public static VideoFlipConfig GetVideoFlipConfig()
        {
            var flipHorizontally = Settings.Default.HorizontalFlip;
            var flipVertically = Settings.Default.VerticalFlip;
            var typeCode = ActiveApp.Instance.GetEndoscopicTypeCode();
            if (typeCode != null)
            {
                var flipConfig = AppConfigHelper.GetVideoFlipConfig(typeCode);
                if (flipConfig != null)
                {
                    flipHorizontally = flipHorizontally || flipConfig.FlipHorizontally;
                    flipVertically = flipVertically || flipConfig.FlipVertically;
                }
                else
                {
                    Logger.Warn("load VideoFlipConfig failed,typecode=" + typeCode);
                }
            }

            return new VideoFlipConfig(flipHorizontally, flipVertically);
        }

        /// <summary>
        /// 准备运行实验
        /// </summary>
        /// <param name="instManager"></param>
        /// <param name="exper"></param>
        /// <param name="retryTimes">获取视频信息失败重试次数</param>
        /// <returns>运行相关参数</returns>
        public static async Task<ExperRunParams> PrepareStartRecord(InstrumentManager instManager, ExperInfo exper, int retryTimes = 1)
        {
            var instState = instManager.Instrument;

            // 内窥镜配置
            var config = AppConfigHelper.GetEndoscopicConfigByHcSerialNo(instState.HcSerialNo);
            if (config == null)
            {
                // 请确认上位机软件是否为最新版本
                MessageHelper.ShowErrorByMsgId("Run.CannotFoundConfigBySerialNo");
                return null;
            }

            bool hcNeedReplace = false;

            var deadlineTime = instState.FactoryTime.AddMonths(config.ShelfLifeMonths);
            if (deadlineTime < DateTime.Now)
            {
                // 超过设定的有效期后、禁止使用
                // Run.CannotUseBecauseOfExpired=Model={0}，SN={1} 内窥镜超过有效期，禁止使用
                var msg = I18nHelper.Default.GetMessageWithArgs("Run.CannotUseBecauseOfExpired",
                   config.Model, instState.HcSerialNo);
                MessageHelper.ShowError(msg);
                return null;
            }

            // Reusable时，不检查使用时间
            if (!config.Reusable)
            {
                if (instState.HcUsedTime > 0)
                {
                    if (instState.HcUsedTime > 0x77)
                    {
                        // 78~FE则直接提示:”Model = LAN - EP - 2512，SN = A1xxxx内窥镜已使用，请更换！”
                        hcNeedReplace = true;
                    }
                    else
                    {
                        try
                        {
                            // 获取首次运行时间
                            var packet = instManager.SendAndWaitResponse(PacketHelper.CreateReadFirstRunTime());
                            var firstRunTime = PacketHelper.DecodeReadFirstRunTime(packet);

                            if (firstRunTime.AddHours(24) < DateTime.Now)
                            {
                                // 首次运行已超过24小时
                                hcNeedReplace = true;
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex);
                            MessageHelper.ShowError(ex.Message);
                            return null;
                        }
                    }
                }

                //  ”Model = LAN - EP - 2512，SN = A1xxxx内窥镜已使用，请更换！”
                if (hcNeedReplace)
                {
                    var msg = I18nHelper.Default.GetMessage("Run.CannotReuse");
                    msg = string.Format(msg, config.Model, instState.HcSerialNo);
                    MessageHelper.ShowError(msg);
                    return null;
                }

                // 01~77提示:”Model = LAN - EP - 2512，SN = A1xxxx已使用，是否继续 ?”
                if (instState.HcUsedTime is >= 1 and <= 0x77)
                {
                    var msg = I18nHelper.Default.GetMessage("Run.ConfirmReuse");
                    msg = string.Format(msg, config.Model, instState.HcSerialNo);
                    var r = await MessageHelper.ShowYesNoAsync(msg);
                    if (r != MessageBoxResult.Yes)
                    {
                        return null;
                    }
                }
            }

            // 查找视频源
            string videoInputName = await GetVideoInputName(config.TypeCode, retryTimes);

            if (videoInputName == null)
                return null;

            // 初始化要运行的实验
            short videoWidth = (short)config.HorizontalResolution;
            short videoHeight = (short)config.VerticalResolution;
            ExperManager.Default.InitExperWhenExperStart(exper, videoWidth, videoHeight, instState);

            // 返回运行相关参数
            return new ExperRunParams
            {
                VideoHeight = videoHeight,
                VideoWidth = videoWidth,
                VideoInputName = videoInputName,
                VideoFormat = config.VideoFormat
            };
        }

        private static async Task<string> GetVideoInputName(string typeCode, int retryTimes)
        {
            // 查找视频源
            string videoInputName = null;
            if (retryTimes < 1) retryTimes = 1;

            var failTimes = 0;
            IProgressController pdc = null;
            try
            {
                while (retryTimes-- > 0)
                {
                    if (pdc is { IsDisposed: true })
                        break;
                    try
                    {
                        // 释放设备
                        HCameraLib.hFreeVideoDevice();

                        var deviceIndex = CameraLib.FindVideoDeviceIndex(typeCode);
                        videoInputName = CameraLib.GetDeviceName(deviceIndex);
                        break;
                    }
                    catch (Exception ex)
                    {
                        failTimes++;
                        Logger.Error(ex);
                        if (ex.Message == I18nHelper.Default.GetMessage("FailedToEnumVideoDevice"))
                        {
                            // 如果需要重试，则显示进度条
                            if (retryTimes > 1 && failTimes == 1)
                            {
                                // 正在获取视频设备...
                                pdc = await WaitBoxHelper.WaitBox.ShowAsync("", I18nHelper.Default.GetMessage("FindingVideoDevice"), true, false);
                            }

                            // 最后一次尝试失败
                            if (retryTimes == 0)
                            {
                                pdc?.Dispose();
                                pdc = null;
                                MessageHelper.ShowError(ex.Message);
                                return null;
                            }

                            for (int i = 0; i < 10; i++)
                            {
                                await Task.Delay(100);
                                if (pdc is { IsDisposed: true })
                                    break;
                            }

                            continue;
                        }

                        pdc?.Dispose();
                        pdc = null;
                        MessageHelper.ShowError(ex.Message);
                        return null;
                    }
                }
            }
            finally
            {
                pdc?.Dispose();
            }

            return videoInputName;
        }
    }
}
